package cn.wjzhang.core.aspect;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.wjzhang.core.annotation.AutoLog;
import cn.wjzhang.core.beans.request.SysLogAddRequest;
import cn.wjzhang.core.utils.IPUtils;
import com.alibaba.fastjson.JSONObject;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * ========================
 * 系统日志切面处理类
 *
 * @author wjzhang
 * @version v1.0
 * ========================
 * @date 2023/6/20 9:51
 */
@Aspect
@Component
public class AutoLogAspect {

    /**
     * 切点为加@AutoLog注解
     */
    @Pointcut("@annotation(cn.wjzhang.core.annotation.AutoLog)")
    public void logPointCut() {

    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {

        // hutool工具类计时
        TimeInterval timer = DateUtil.timer();

        //执行方法
        Object result = point.proceed();

        //执行时长(毫秒)
        long executionTime = timer.intervalMs();

        // 保存日志
        saveSysLog(point, result, executionTime);

        return result;
    }

    // 保存日志
    private void saveSysLog(ProceedingJoinPoint joinPoint, Object result, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        SysLogAddRequest sysLogAddRequest = new SysLogAddRequest();

        // 注解信息
        AutoLog autoLog = method.getAnnotation(AutoLog.class);
        if (autoLog != null) {
            //注解上的描述,操作日志内容
            sysLogAddRequest.setAppId(autoLog.appId());
            sysLogAddRequest.setAppName(autoLog.appName());
            sysLogAddRequest.setLogContent(autoLog.value());
            sysLogAddRequest.setLogType(autoLog.logType().getCode());
            sysLogAddRequest.setOperateType(autoLog.operationType().getCode());
        }

        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLogAddRequest.setMethod(className + "." + methodName + "()");

        // 获取request
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        // 设置IP地址
        sysLogAddRequest.setIp(IPUtils.getClientIp(request));

        // 请求的参数
        Object[] args = joinPoint.getArgs();
        try {
            String params = JSONObject.toJSONString(args);
            sysLogAddRequest.setRequestParam(params);
        } catch (Exception e) {
            System.out.println("");
        }

        // 响应结果
        String responseJson = JSONObject.toJSONString(result);
        sysLogAddRequest.setResponse(responseJson);

        //获取登录用户信息
        // 解析agent字符串
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        // 获取浏览器对象
        Browser browser = userAgent.getBrowser();
        // 获取操作系统对象
        OperatingSystem operatingSystem = userAgent.getOperatingSystem();
        System.out.println("浏览器名：" + browser.getName());
        System.out.println("浏览器类型：" + browser.getBrowserType());
        System.out.println("浏览器家族：" + browser.getGroup());
        System.out.println("浏览器生产厂商：" + browser.getManufacturer());
        System.out.println("浏览器使用的渲染引擎：" + browser.getRenderingEngine());
        System.out.println("浏览器版本：" + userAgent.getBrowserVersion());
        System.out.println("==================================================" );
        System.out.println("==================================================" );
        System.out.println("操作系统名：" + operatingSystem.getName());
        System.out.println("访问设备类型：" + operatingSystem.getDeviceType());
        System.out.println("操作系统家族：" + operatingSystem.getGroup());
        System.out.println("操作系统生产厂商：" + operatingSystem.getManufacturer());

//		LoginInfo sysUser = LoginContextUtils.getCurrentUser();
//		if (sysUser != null) {
//			sysLogAddRequest.setUserId(sysUser.getUserName());
//			sysLogAddRequest.setUsername(sysUser.getRealName());
//		}
        // 耗时
        sysLogAddRequest.setCostTime(time);

        // 保存系统日志 TODO 数据入库
//        SysLogClient sysLogClient = SpringUtil.getBean(SysLogClient.class);
//        sysLogClient.add(sysLogAddRequest);
        System.out.println(JSONObject.toJSONString(browser));
        System.out.println(JSONObject.toJSONString(sysLogAddRequest));
        System.out.println(responseJson);
    }


}
